package com.zhanglijie.improve.collections.delayqueue.demo.timecache;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author zhanglijie
 * @version 1.0
 * @since 1.1.0 2022/12/4 0004 19:58
 * 实现一个带时间的缓存
 */
public class TimeCache<K,V> {
    //本地缓存-如果time到了就从缓存中移除
    private ConcurrentHashMap<K,V> cacheMap = new ConcurrentHashMap();
    //辅助过期时间用的
    private DelayQueue<DelayObject<KeyAndValue<K,V>>> queue = new DelayQueue<>();
    public TimeCache(){
        Runnable task = ()->{
            watchCheck();
        };
        Thread thread = new Thread(task);
        thread.setName("cache watch");
        thread.setDaemon(true);
        thread.start();
    }
    private void watchCheck(){
        System.out.println("cache service started....");
        for(;;){
            try {
                DelayObject<KeyAndValue<K, V>> take = queue.take();
                if (take != null) {
                    KeyAndValue item = take.getItem();
                    cacheMap.remove(item.key,item.value);
                }
            }catch (Exception e){
                e.printStackTrace();
                break;
            }
        }
        System.out.println("cache service stoped....");
    }
    public V get(K key){
       return cacheMap.get(key);
    }
    public void put(K key,V value,long time, TimeUnit unit){
        V oldValue = cacheMap.put(key, value);
        if(oldValue != null){//替换更新老值
            queue.remove(oldValue);//讲delay中对应的老值也删除
        }
        long nanos = TimeUnit.NANOSECONDS.convert(time, unit);
        queue.put(new DelayObject<KeyAndValue<K,V>>(new KeyAndValue<K,V>(key,value),nanos));
    }
}
